home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 3_0 / MENUDEMO / MENU.C < prev    next >
C/C++ Source or Header  |  1989-02-09  |  6KB  |  258 lines

  1. /*
  2.  * menu.c - MenuDemo: a demo of a custom Menu Definition.
  3.  *
  4.  * How to build this program:
  5.  *    1) In the "crushproj" project, create the CODE resource, "crush.mdef".
  6.  *    2) Run RMaker on the file "menu.r".
  7.  *    3) Use ResEdit to edit "crushproj.rsrc", changing the proc-id of each
  8.  *       menu from 0 (the stock MDEF) to 400 (our custom MDEF's resource ID).
  9.  *    4) In the "menuproj" project, Build the Application, MenuDemo.
  10.  */
  11.  
  12. #include <MacTypes.h>
  13. #include <Quickdraw.h>
  14. #include <MemoryMgr.h>
  15. #include <WindowMgr.h>
  16. #include <DialogMgr.h>
  17. #include <MenuMgr.h>
  18. #include <EventMgr.h>
  19. #include <DeskMgr.h>
  20. #include <ControlMgr.h>
  21. #include <TextEdit.h>
  22. #include <PackageMgr.h>
  23. #include <ToolboxUtil.h>
  24. #include <pascal.h>
  25.  
  26. /*
  27.  * LINKED_MDEF - Set to '1' if the MDEF is really a subroutine that we're
  28.  * testing; Set to '0' otherwise.
  29.  *
  30.  * This definition makes it easy to debug a new MDEF by having this program
  31.  * call our menu definition subroutine directly
  32.  * (rather than calling MenuSelect()).
  33.  *
  34.  * To use this feature, add the menu definition code to this program's project
  35.  * (so it gets linked in) and change the MDEF's entry point name from "main"
  36.  * to "mymenu".
  37.  *
  38.  * When you're done debugging, change LINKED_MDEF to '0', change the MDEF's
  39.  * entry name back to "main", and remove the MDEF's code from this project.
  40.  */
  41.  
  42. #define LINKED_MDEF 0
  43.  
  44. /**********
  45.  * Garden-variety declarations for this program follow.
  46.  * they're not really part of the demo.
  47.  **********/
  48.  
  49. #define APPLEMENU    1    /* Menu ID for Apple menu    */
  50. #define FILEMENU    2    /* ...File menu                */
  51. #define DEMOMENU    3    /* ...Demo menu                */
  52. #define LASTMENU    3    /* Number of menus            */
  53.  
  54. #define DLG_ABOUT    256    /* ResID of the About... dialog */
  55.  
  56. MenuHandle mymenus[LASTMENU + 1]; /* menus[1..LASTMENU]    */
  57.  
  58. #define maxStackSize 8192    /* max size of our stack */
  59.  
  60. /*
  61.  * screenport - used to keep the current port from ever dangling.
  62.  *   This is a port for the whole screen.
  63.  */
  64.  
  65. GrafPtr screenport;
  66.  
  67. /***************
  68.  * The following routines are just boilerplate.
  69.  * They aren't part of the virus detection code.
  70.  ***************/
  71.  
  72. /*
  73.  * main() - run the program.
  74.  */
  75.  
  76. main()
  77. {
  78.     long *stackbaseptr;            /* points to current stack base */
  79.     int i;
  80.  
  81.     /*
  82.      * Initialize our memory,
  83.      * then init the Toolbox managers (order is important).
  84.      */
  85.  
  86.     stackbaseptr = (long *) 0x908;
  87.     SetApplLimit((Ptr) (*stackbaseptr - maxStackSize));
  88.     MaxApplZone();
  89.     MoreMasters();
  90.     MoreMasters();
  91.  
  92.     InitGraf(&thePort);
  93.     InitFonts();
  94.     InitWindows();
  95.     InitMenus();
  96.     TEInit();
  97.     InitDialogs((ProcPtr) 0);
  98.     DILoad();
  99.     SetEventMask(everyEvent - keyUpMask);
  100.     InitCursor();
  101.     GetWMgrPort(&screenport);
  102.     SetPort(screenport);
  103.  
  104.     /*
  105.      * Setup our menus, then do nothing until we quit.
  106.      */
  107.  
  108.     for (i = 1; i <= LASTMENU; i++) {
  109.         mymenus[i] = GetMenu(i);
  110.         InsertMenu(mymenus[i], 0);
  111.     }
  112.     DrawMenuBar();
  113.  
  114.     while (doevent())
  115.         ;
  116.     InitCursor();
  117.     SetEventMask(everyEvent - keyUpMask);
  118. }
  119.  
  120. /*
  121.  * doevent() - one loop through the main event handler
  122.  */
  123.  
  124. int        /* "do another event"    */
  125. doevent()
  126. {
  127.     EventRecord myevent;    /* the event to handle */
  128.     WindowPtr whichwindow;    /* Points to window of MouseDown */
  129.     char whichchar;            /* the character typed */
  130.     long menucommand;        /* a menu command to do (menu + item) */
  131.     int windowcode;            /* What mouse was in when event posted */
  132.     int userdone;            /* True when user wants to exit program */
  133.  
  134.     userdone = FALSE;
  135.     SystemTask();            /* give the system a moment of time    */
  136.  
  137.     if (!GetNextEvent(everyEvent, &myevent)) {
  138.         /* We're idle. */
  139.     } else if ((myevent.modifiers & cmdKey) &&
  140.       (myevent.what == keyDown || myevent.what == autoKey)) {
  141.     
  142.         /*
  143.          * It's a command-key keystroke.
  144.          * (command keystrokes are handled here since dialogs can't)
  145.          */
  146.     
  147.         whichchar = (char) (myevent.message & charCodeMask);
  148.         menucommand = MenuKey(whichchar);
  149.         userdone = docommand(menucommand);
  150.     } else if (IsDialogEvent(&myevent)) {
  151.         /* here's where we'd handle modeless dialog events */
  152.     } else {
  153.         switch (myevent.what) {
  154.         case mouseDown:            /* a mouse click someplace    */
  155.             windowcode = FindWindow(myevent.where, &whichwindow);
  156.             if (windowcode == inMenuBar) {
  157.                 menucommand = MenuSelect(myevent.where);
  158.                 userdone = docommand(menucommand);
  159.                 break;
  160.             } else {
  161. #if LINKED_MDEF
  162.                 int theitem;
  163.                 
  164.                 theitem = dumbmenu(myevent.where);
  165. #endif
  166.             }
  167.             break;
  168.         }
  169.     }
  170.     return(!userdone);
  171. }
  172.  
  173. /*
  174.  * docommand() - handle a command given through a menu selection.
  175.  */
  176.  
  177. int        /* "the command was 'quit' */
  178. docommand(mresult)
  179. long    mresult;    /* the command to execute (a menu item)    */
  180. {
  181.     int themenu;        /* menu the mouse chose */
  182.     int theitem;        /* item in that menu */
  183.     int     returns;        /* value to be returned */
  184.     short itemhit;        
  185.     DialogPtr reportptr;
  186.  
  187.     returns = FALSE;
  188.     themenu = HiWord(mresult);
  189.     theitem = LoWord(mresult);
  190.     
  191.     switch (themenu) {
  192.     case APPLEMENU:            /* Tell about the program */
  193.         reportptr = GetNewDialog(DLG_ABOUT, (char *) 0, (long) -1);
  194.         ModalDialog((ProcPtr) 0, &itemhit);
  195.         DisposDialog(reportptr);
  196.         break;
  197.  
  198.     case FILEMENU:            /* quit */
  199.         returns = TRUE;
  200.         break;
  201.     }
  202.     HiliteMenu(0);
  203.     return(returns);
  204. }
  205.  
  206. #if LINKED_MDEF
  207.  
  208. /*
  209.  * dumbmenu() - pretend to be MenuSelect(),
  210.  * calling the appropriate operations in the MDEF we're testing.
  211.  *
  212.  * This arrangement lets us quickly debug a new MDEF under Lightspeed C
  213.  * without going to the hassle of generating a real MDEF each time we
  214.  * make a change.
  215.  */
  216.  
  217. int  /* the item # */
  218. dumbmenu(pt)
  219. Point pt;    /* mouse-down (global coords) */
  220. {
  221.     MenuHandle menuh;        /* the menu we're working with */
  222.     Rect menurect;            /* the rect bounding the menu */
  223.     int theitem;            /* the selected item number */
  224.     Rect tmprect;
  225.     pascal void mymenu();    /* the name of our MDEF subroutine */
  226.     
  227.     menuh = mymenus[DEMOMENU];
  228.     menurect.top = 0;
  229.     menurect.left = 0;
  230.     menurect.bottom = 0;
  231.     menurect.right = 0;
  232.     theitem = 0;
  233.     
  234.     mymenu((int) mSizeMsg, menuh, &menurect, pt, &theitem);
  235.     
  236.     menurect.top = 50;
  237.     menurect.left = 30;
  238.     menurect.bottom = menurect.top + (*menuh)->menuHeight;
  239.     menurect.right = menurect.left + (*menuh)->menuWidth;
  240.     
  241.     EraseRect(&menurect);
  242.     tmprect = menurect;
  243.     InsetRect(&tmprect, -1, -1);
  244.     FrameRect(&tmprect);
  245.     MoveTo(tmprect.left + 2, tmprect.bottom);
  246.     LineTo(tmprect.right, tmprect.bottom);
  247.     LineTo(tmprect.right, tmprect.top + 2);
  248.  
  249.     mymenu((int) mDrawMsg, menuh, &menurect, pt, &theitem);
  250.     while (StillDown()) {
  251.         GetMouse(&pt);
  252.         LocalToGlobal(&pt);
  253.         mymenu((int) mChooseMsg, menuh, &menurect, pt, &theitem);
  254.     }
  255.     EraseRect(&menurect);
  256. }
  257. #endif
  258.